home *** CD-ROM | disk | FTP | other *** search
/ One Click 14 / OneClick14.iso / Ferramentas / Convert XLS to Pdf / xls2pdf_setup.exe / {app} / lib / pdf_draw.ps < prev    next >
Encoding:
Text File  |  2002-11-21  |  37.8 KB  |  1,248 lines

  1. %    Copyright (C) 1994, 2000 Aladdin Enterprises.  All rights reserved.
  2. % This software is provided AS-IS with no warranty, either express or
  3. % implied.
  4. % This software is distributed under license and may not be copied,
  5. % modified or distributed except as expressly authorized under the terms
  6. % of the license contained in the file LICENSE in this distribution.
  7. % For more information about licensing, please refer to
  8. % http://www.ghostscript.com/licensing/. For information on
  9. % commercial licensing, go to http://www.artifex.com/licensing/ or
  10. % contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  11. % San Rafael, CA  94903, U.S.A., +1(415)492-9861.
  12.  
  13. % $Id: pdf_draw.ps,v 1.63 2002/11/21 01:29:07 alexcher Exp $
  14. % pdf_draw.ps
  15. % PDF drawing operations (graphics, text, and images).
  16.  
  17. /.setlanguagelevel where { pop 2 .setlanguagelevel } if
  18. .currentglobal true .setglobal
  19. /pdfdict where { pop } { /pdfdict 100 dict def } ifelse
  20. GS_PDF_ProcSet begin
  21. pdfdict begin
  22.  
  23. % For simplicity, we use a single interpretation dictionary for all
  24. % PDF graphics operations, even though this is too liberal.
  25. /drawopdict 100 dict def
  26.  
  27. % ================================ Graphics ================================ %
  28.  
  29. % ---------------- Functions ---------------- %
  30.  
  31. % Note that resolvefunction converts a PDF Function to a PostScript Function;
  32. % resolve*fnproc converts a PDF function to a PostScript procedure.
  33. % We need to process all required and optional parameters to resolve any
  34. % use of indirect references.
  35.  
  36. /fnrdict mark
  37.   0 { .resolvefn0 }
  38.   2 { .resolvefn2 }
  39.   3 { .resolvefn3 }
  40.   4 { .resolvefn4 }
  41. .dicttomark readonly def
  42.  
  43. /.resolvefn0 {
  44.   dup length 1 add dict .copydict    % make room for DataSource
  45.   % now resolve any indirect references
  46.   dup /Size 2 copy knownoget { put } { pop pop } ifelse
  47.   dup /BitsPerSample 2 copy knownoget { put } { pop pop } ifelse
  48.   dup /Order 2 copy knownoget { put } { pop pop } ifelse
  49.   dup /Encode 2 copy knownoget { put } { pop pop } ifelse
  50.   dup /Decode 2 copy knownoget { put } { pop pop } ifelse
  51.   
  52.         % Don't lose our place in PDFfile.
  53.   PDFfile fileposition exch
  54.   dup true resolvestream
  55.         % The stream isn't positionable, so read all the data now.
  56.         % Stack: filepos fndict stream
  57.   1 index /Range get length 2 idiv 2 index /BitsPerSample get mul
  58.   2 index /Size get { mul } forall
  59.   7 add 8 idiv string
  60.   1 index exch readstring pop exch closefile
  61.         % Stack: filepos fndict data
  62.   exch dup /DataSource 4 -1 roll put
  63.   exch PDFfile exch setfileposition
  64. } bdef
  65.  
  66. /.resolvefn2 {
  67.   dup length dict .copydict
  68.   dup /C0 2 copy knownoget { put } { pop pop } ifelse
  69.   dup /C1 2 copy knownoget { put } { pop pop } ifelse
  70.   dup /N 2 copy knownoget { put } { pop pop } ifelse
  71. } bdef
  72.  
  73. /.resolvefn3 {
  74.   dup length dict .copydict
  75.   dup /Bounds 2 copy knownoget { put } { pop pop } ifelse
  76.   dup /Encode 2 copy knownoget { put } { pop pop } ifelse
  77.   dup /Functions 2 copy oget mark exch dup {
  78.     oforce .resolvefn
  79.   } forall
  80.   counttomark -1 roll astore exch pop put
  81. } bdef
  82.  
  83. /.resolvefn4 {
  84.   PDFfile fileposition exch             % filepos fndict
  85.   dup true resolvestream                % filepos fndict stream
  86.   exch dup length dict copy             % filepos stream fndict2
  87.   dup /Function undef                   % filepos stream fndict2
  88.   exch dup token not {
  89.     () /rangecheck cvx signalerror
  90.   } if
  91.   exch token {
  92.     /rangecheck cvx signalerror
  93.   } if
  94.         % Use .bind to avoid idiom recognition.
  95.   .bind
  96.   1 index /Function 3 -1 roll put
  97.   exch PDFfile exch setfileposition
  98. } bdef
  99.  
  100. /.resolvefn {        % <fndict> .resolvefn <fndict'>
  101.   dup length dict .copydict
  102.   dup /Domain 2 copy knownoget { put } { pop pop } ifelse
  103.   dup /Range 2 copy knownoget { put } { pop pop } ifelse
  104.   dup /FunctionType oget //fnrdict exch get exec
  105. } bdef
  106.  
  107. /resolvefunction {    % <fndict> resolvefunction <function>
  108.   .resolvefn
  109.   DEBUG { (%Function: ) print dup === flush } if
  110. } bdef
  111.  
  112. /resolvefnproc {    % <fndict> resolvefnproc <proc>
  113.   resolvefunction .buildfunction
  114. } bdef
  115.  
  116. /resolveidfnproc {    % <fndict> resolveidfnproc <proc>
  117.   dup /Identity eq { pop { } } { resolvefnproc } ifelse
  118. } bdef
  119.  
  120. /resolvedefaultfnproc {    % <fndict> <default> resolved'fnproc <proc>
  121.   1 index /Default eq { exch pop } { pop resolveidfnproc } ifelse
  122. } bdef
  123.  
  124. % ---------------- Shadings ---------------- %
  125.  
  126. /shrdict mark
  127.   /ColorSpace {
  128.     resolvecolorspace
  129.   }
  130.   /Function {
  131.     dup type /dicttype eq {
  132.       resolvefunction
  133.     } {
  134.       [ exch { oforce resolvefunction } forall ]
  135.     } ifelse
  136.   }
  137. .dicttomark readonly def
  138.  
  139. /resolveshading {    % <shadingstream> resolveshading <shading>
  140.   PDFfile fileposition exch
  141.   mark exch {
  142.     oforce //shrdict 2 index .knownget { exec } if
  143.   } forall .dicttomark
  144.   dup /ShadingType get 4 ge {
  145.     dup dup true resolvestream
  146.         % Make a reusable stream so that the shading doesn't
  147.         % reposition PDFfile at unexpected times.
  148.     /ReusableStreamDecode filter /DataSource exch put
  149.   } if exch PDFfile exch setfileposition
  150. } bdef
  151. /resolvesh {        % <shname> resolveshading <shading>
  152.   Page /Shading rget {
  153.     resolveshading
  154.   } {
  155.     null
  156.   }ifelse
  157. } bdef
  158.  
  159. % ---------------- Halftones ---------------- %
  160.  
  161. /spotfunctions mark
  162.   /Round {
  163.     abs exch abs 2 copy add 1 le {
  164.       dup mul exch dup mul add 1 exch sub 
  165.     } {
  166.       1 sub dup mul exch 1 sub dup mul add 1 sub
  167.     } ifelse
  168.   }
  169.   /Diamond {
  170.     abs exch abs 2 copy add .75 le {
  171.       dup mul exch dup mul add 1 exch sub
  172.     } {
  173.       2 copy add 1.23 le {
  174.     .85 mul add 1 exch sub
  175.       } {
  176.     1 sub dup mul exch 1 sub dup mul add 1 sub
  177.       } ifelse
  178.     } ifelse
  179.   }
  180.   /Ellipse {
  181.     abs exch abs 2 copy 3 mul exch 4 mul add 3 sub dup 0 lt {
  182.       pop dup mul exch .75 div dup mul add 4 div 1 exch sub
  183.     } {
  184.       dup 1 gt {
  185.     pop 1 exch sub dup mul exch 1 exch sub
  186.     .75 div dup mul add 4 div 1 sub
  187.       } {
  188.     .5 exch sub exch pop exch pop
  189.       } ifelse
  190.     } ifelse
  191.   }
  192.   /EllipseA { dup mul .9 mul exch dup mul add 1 exch sub }
  193.   /InvertedEllipseA { dup mul .9 mul exch dup mul add 1 sub }
  194.   /EllipseB { dup 5 mul 8 div mul exch dup mul exch add sqrt 1 exch sub }
  195.   /EllipseC { dup mul .9 mul exch dup mul add 1 exch sub }
  196.   /InvertedEllipseC { dup mul .9 mul exch dup mul add 1 sub }
  197.   /Line { exch pop abs neg }
  198.   /LineX { pop }
  199.   /LineY { exch pop }
  200.   /Square { abs exch abs 2 copy lt { exch } if pop neg }
  201.   /Cross { abs exch abs 2 copy gt { exch } if pop neg }
  202.   /Rhomboid { abs exch abs 0.9 mul add 2 div }
  203.   /DoubleDot { 2 {360 mul sin 2 div exch } repeat add }
  204.   /InvertedDoubleDot { 2 {360 mul sin 2 div exch } repeat add neg }
  205.   /SimpleDot { dup mul exch dup mul add 1 exch sub }
  206.   /InvertedSimpleDot { dup mul exch dup mul add 1 sub }
  207.   /CosineDot { 180 mul cos exch 180 mul cos add 2 div }
  208.   /Double { exch 2 div exch 2 { 360 mul sin 2 div exch } repeat add }
  209.   /InvertedDouble {
  210.     exch 2 div exch 2 { 360 mul sin 2 div exch } repeat add neg
  211.   }
  212. .dicttomark readonly def
  213.  
  214. /htrdict mark
  215.   1 { .resolveht1 }
  216.   5 { .resolveht5 }
  217.     % We don't support types 6, 10, or 16 yet.
  218. .dicttomark readonly def
  219.  
  220. /.resolveht1 {
  221.   mark exch {
  222.     oforce
  223.     1 index /SpotFunction eq {
  224.       dup type /nametype eq
  225.     { //spotfunctions exch get } { resolvefnproc }
  226.       ifelse
  227.     } {
  228.       1 index /TransferFunction eq {
  229.     resolveidfnproc
  230.       } if
  231.     } ifelse
  232.   } forall .dicttomark
  233. } bdef
  234.  
  235. /.resolveht5 {
  236.   mark exch {
  237.     oforce dup type /dicttype eq { resolvehalftone } if
  238.   } forall .dicttomark
  239. } bdef
  240.  
  241. /resolvehalftone {    % <dict> resolvehalftone <halftone>
  242.   dup /HalftoneType get
  243.   dup //htrdict exch .knownget {
  244.     exch pop exec
  245.   } {
  246.     (\n\n   **** Unsupported HalftoneType ) pdfformaterror
  247.     =string cvs pdfformaterror (. ***\n\n) pdfformaterror
  248.     /resolvehalftone cvx /unregistered signalerror
  249.   } ifelse
  250. } bdef
  251.  
  252. % ---------------- Graphics state management ---------------- %
  253.  
  254. /cmmatrix matrix def
  255. drawopdict begin
  256.             % Graphics state stack
  257.   /q { q } def
  258.   /Q { Q } def
  259.             % Graphics state setting
  260.   /cm { //cmmatrix astore concat } def
  261.   /i { 1 .min setflat } def
  262.   /J /setlinecap load def
  263.   /d /setdash load def
  264.   /j /setlinejoin load def
  265.   /w /setlinewidth load def
  266.   /M /setmiterlimit load def
  267.   /gs { gs } def
  268. end
  269.  
  270. % Each entry in this dictionary is
  271. %    <gsres> <value> -proc- <gsres>
  272. /gsbg {
  273.   /BGDefault load resolvedefaultfnproc setblackgeneration
  274. } bdef
  275. /gsucr {
  276.   /UCRDefault load resolvedefaultfnproc setundercolorremoval
  277. } bdef
  278. /gstr {
  279.   dup type /arraytype eq {
  280.     { oforce /TRDefault load resolvedefaultfnproc } forall
  281.     setcolortransfer
  282.   } {
  283.     /TRDefault load resolvedefaultfnproc settransfer
  284.   } ifelse
  285. } bdef
  286. /gsparamdict mark
  287.   /SA { setstrokeadjust }
  288.   /OP { 1 index /op known not { dup op } if OP }
  289.     % The PDF 1.3 specification says that the name /Default is only
  290.     % recognized for {BG,UCR,TR}2.  However, PDF 1.3 files produced
  291.     % by Adobe Acrobat Distiller 4.0 for Windows use the name /Default
  292.     % with the older keys, so we have to implement this.
  293.   /BG { 1 index /BG2 known { pop } { gsbg } ifelse }
  294.   /UCR { 1 index /UCR2 known { pop } { gsucr } ifelse }
  295.   /TR { 1 index /TR2 known { pop } { gstr } ifelse }
  296.   /HT {
  297.     dup /Default eq {
  298.       pop .setdefaultscreen
  299.     } {
  300.     %****** DOESN'T IMPLEMENT THE STREAM CASE YET ******
  301.       resolvehalftone sethalftone
  302.     } ifelse
  303.     % the transfer function may dependent on the halftone, so make sure
  304.     % it is set if included in the graphic state (otherwise this is
  305.     % subject to order of a dictionary forall, which is unpredictable)
  306.     dup /TR2 .knownget {
  307.       dup /Default eq { oforce gsparamdict /TR2 get exec } { pop } ifelse
  308.     } {
  309.       dup /TR .knownget {
  310.         /dup /Default eq { oforce gsparamdict /TR get exec } { pop } ifelse
  311.       } if
  312.     } ifelse
  313.   }
  314.   /HTP {
  315.     % HTP may be present even if this isn't a DPS interpreter.
  316.     /sethalftonephase where { pop aload pop sethalftonephase } { pop } ifelse
  317.   }
  318.     % PDF 1.3
  319.   /Font { aload pop Tf }
  320.   /LW { setlinewidth }
  321.   /LC { setlinecap }
  322.   /LJ { setlinejoin }
  323.   /ML { setmiterlimit }
  324.   /D { aload pop setdash }
  325.   /RI { ri }
  326.   /op { op }
  327.   /OPM { OPM }
  328.   /BG2 { gsbg }
  329.   /UCR2 { gsucr }
  330.   /TR2 { gstr }
  331.   /FL { 1 .min setflat }
  332.   /SM {
  333.     % SM may be present even if this is only a Level 2 interpreter.
  334.     /setsmoothness where { pop setsmoothness } { pop } ifelse
  335.   }
  336.     % PDF 1.4
  337.     % All of these require the "transparency" feature in the interpreter.
  338.   /ca { ca }
  339.   /CA { CA }
  340.   /SMask { gssmask }
  341.   /AIS { AIS }
  342.   /BM { BM }
  343.   /TK { TK }
  344. .dicttomark readonly def
  345. /gs {            % <gsres> gs -
  346.   Page /ExtGState rget {
  347.     % We keep the dictionary on the stack during the forall so that
  348.     % keys that interact with each other have access to it.
  349.     dup {
  350.       oforce exch gsparamdict exch .knownget { exec } { pop } ifelse
  351.     } forall pop
  352.   } if
  353. } bdef
  354.  
  355. % ------ Transparency support ------ %
  356.  
  357. /gssmask {
  358.   dup /None eq {
  359.     pop null
  360.   } {
  361.     % Preprocess the SMask value into a parameter dictionary for
  362.     % .begintransparencymask, with added /BBox and /Draw keys.
  363.     mark exch        % Stack: mark smaskdict
  364.     dup /S oget /Subtype exch 3 2 roll
  365.             % Stack: mark ... smaskdict
  366.     dup /BC knownoget { /Background exch 3 2 roll } if
  367.     dup /TR knownoget {
  368.       resolveidfnproc /TransferFunction exch 3 2 roll
  369.     } if    
  370.     dup /G oget dup /BBox oget /BBox exch 4 2 roll
  371.     /.execmaskgroup cvx 2 packedarray cvx /Draw exch 3 2 roll
  372.     pop .dicttomark
  373.   } ifelse SMask
  374. } bdef
  375.  
  376. % This procedure is called to actually render the soft mask.
  377. /.execmaskgroup {    % <masknum> <paramdict> <formdict> .execmaskgroup -
  378.     % Save our place in PDFfile, and do a gsave to avoid resetting
  379.     % the color space.
  380.   gsave PDFfile fileposition 4 1 roll
  381.     % We have to select the group's color space so that the
  382.     % background color will be interpreted correctly.
  383.   dup /Group oget /CS knownoget { csresolve setgcolorspace } if
  384.   exch dup /BBox get aload pop .begintransparencymask {
  385.     dup /Resources knownoget { oforce } { 0 dict } ifelse
  386.     exch false resolvestream
  387.     .execgroup .endtransparencymask
  388.   } .internalstopped {
  389.     .discardtransparencymask stop
  390.   } if
  391.   PDFfile exch setfileposition grestore
  392. } bdef
  393. % Paint a Form+Group XObject, either for a transparency mask or for a Do.
  394. /.execgroup {        % <resdict> <stream> .execgroup -
  395.   gsave
  396.   1 .setopacityalpha 1 .setshapealpha
  397.   0 .inittransparencymask 1 .inittransparencymask
  398.   /Compatible .setblendmode
  399.     % Execute the body of the Form, similar to DoForm.
  400.   pdfopdict .pdfruncontext
  401.   grestore
  402. } bdef
  403.  
  404. /.beginformgroup {    % groupdict bbox .beginformgroup -
  405.   exch mark exch            % bbox mark groupdict
  406.   dup /CS knownoget { csresolve setgcolorspace } if
  407.   dup /I knownoget { /Isolated exch 3 2 roll } if
  408.   dup /K knownoget { /Knockout exch 3 2 roll } if
  409.   pop .dicttomark
  410.         % Stack: bbox paramdict
  411.   exch aload pop
  412.   .begintransparencygroup
  413. } bdef
  414.  
  415. % .paintgroupform implements the Form PaintProc in the case where the
  416. % Form XObject dictionary includes a Group key.  See .paintform below.
  417. /.paintgroupform {    % <resdict> <stream> <formdict> .paintgroupform -
  418.   dup /Group oget exch /BBox oget
  419.         % Stack: resdict stream groupdict bbox
  420.   .beginformgroup {
  421.     .execgroup
  422.   } .internalstopped {
  423.     .discardtransparencygroup stop
  424.   } if .endtransparencygroup
  425. } bdef
  426.  
  427. % Make an ImageType 103 (soft-masked) image.
  428. /makesoftmaskimage {    % <datasource> <imagemask> <SMask> makesoftmaskimage
  429.             %   <datasource> <imagemask>, updates currentdict =
  430.             %   imagedict
  431.         % See the ImageType 3 case of makemaskimage below.
  432.         % SMask is a stream, another Image XObject.
  433.         % Stack: datasource imagemask(false) smaskstreamdict
  434.   PDFfile fileposition exch
  435.   dup /Matte knownoget { /Matte exch def } if
  436.   dup length dict makeimagedict pop
  437.         % In order to prevent the two data sources from being
  438.         % aliased, we need to make at least one a reusable stream.
  439.         % We pick the mask, since it's smaller (in case we need to
  440.         % read all its data now).
  441.         % Stack: datasource imagemask(false) savedpos
  442.         % maskdict is currentdict
  443.   /DataSource DataSource mark
  444.     /Intent 1
  445.     /AsyncRead true
  446.   .dicttomark .reusablestreamdecode def
  447.   PDFfile exch setfileposition
  448.   currentdict end currentdict end
  449.   5 dict begin
  450.   /ImageType 103 def
  451.   /DataDict exch def
  452.   dup /InterleaveType 3 put
  453.   DataDict /Matte knownoget {
  454.     /Matte exch def
  455.   } if
  456.   AlphaIsShape { /ShapeMaskDict } { /OpacityMaskDict } ifelse exch def
  457.   /ColorSpace DataDict /ColorSpace get def
  458. } bdef
  459.  
  460. % ---------------- Color setting ---------------- %
  461.  
  462. /01_1 [0 1] readonly def
  463. /01_3 [0 1 0 1 0 1] readonly def
  464. /01_4 [0 1 0 1 0 1 0 1] readonly def
  465.  
  466. % The keys here are resolved (PostScript, not PDF) color space names.
  467. /csncompdict mark
  468.   /DeviceGray { pop 1 }
  469.   /DeviceRGB { pop 3 }
  470.   /DeviceCMYK { pop 4 }
  471.   /CIEBasedA { pop 1 }
  472.   /CIEBasedABC { pop 3 }
  473.   /ICCBased { 1 oget /N oget }
  474.   /Separation { pop 1 }
  475.   /DeviceN { 1 oget length }
  476. .dicttomark readonly def
  477.  
  478. /csrdict mark
  479.   /DeviceGray { }
  480.   /DeviceRGB { }
  481.   /DeviceCMYK { }
  482.   /CalGray {
  483.     1 oget 6 dict begin
  484.     dup /Gamma knownoget {
  485.       /exp load 2 packedarray cvx /DecodeA exch def
  486.     } if
  487.     dup /BlackPoint knownoget { /BlackPoint exch def } if
  488.     dup /WhitePoint knownoget { /WhitePoint exch def } if
  489.     /PDFColorSpace exch def [ /CIEBasedA currentdict end ]
  490.   }
  491.   /CalRGB {
  492.     1 oget 6 dict begin
  493.     dup /Gamma knownoget {
  494.       [ exch { /exp load 2 packedarray cvx } forall
  495.       ] /DecodeABC exch def
  496.     } if
  497.     dup /Matrix knownoget { /MatrixABC exch def } if
  498.     dup /BlackPoint knownoget { /BlackPoint exch def } if
  499.     dup /WhitePoint knownoget { /WhitePoint exch def } if
  500.     /PDFColorSpace exch def [ /CIEBasedABC currentdict end ]
  501.   }
  502.   /CalCMYK {
  503.     pop /DeviceCMYK        % not defined by Adobe
  504.   }
  505.   /Lab {
  506.     1 oget 6 dict begin
  507.     dup /Range knownoget not { [-100 100 -100 100] } if
  508.     [0 100 null null null null] dup 2 4 -1 roll putinterval
  509.     /RangeABC exch def
  510.     /DecodeABC [{16 add 116 div} bind {500 div} bind {200 div} bind] def
  511.     /MatrixABC [1 1 1 1 0 0 0 0 -1] def
  512.     dup /BlackPoint knownoget { /BlackPoint exch def } if
  513.     dup /WhitePoint knownoget { /WhitePoint exch def } {
  514.       (   **** Warning: Lab colorspace is missing WhitePoint.\n)
  515.       pdfformaterror
  516.       /WhitePoint [0.9505 1 1.089] def
  517.     } ifelse
  518.     % scaling function g() for DecodeLMN construction
  519.     { dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse }
  520.     /DecodeLMN [
  521.       % Store white point implicitly inside procedures.
  522.       [ 3 index aload pop WhitePoint 0 get /mul .systemvar ] cvx bind
  523.       [ 4 index aload pop WhitePoint 1 get /mul .systemvar ] cvx bind
  524.       [ 5 index aload pop WhitePoint 2 get /mul .systemvar ] cvx bind
  525.     ] def pop
  526.     /PDFColorSpace exch def [ /CIEBasedABC currentdict end ]
  527.   }
  528.   /ICCBased {
  529.     PDFfile fileposition exch
  530.     dup dup 1 oget
  531.     mark exch { oforce } forall .dicttomark
  532.     dup dup true resolvestream
  533.     /ReusableStreamDecode filter /DataSource exch put
  534.     1 exch put
  535.     exch PDFfile exch setfileposition
  536.   } bind
  537.   /Separation {
  538.     aload pop exch oforce resolvecolorspace exch oforce resolvefnproc
  539.     4 array astore
  540.   }
  541.   /DeviceN {
  542.     0 4 getinterval                    % ignore attributes
  543.     aload pop 3 -1 roll oforce           % resolve names array
  544.     [ exch { oforce } forall ]           % resolve each of the names
  545.     3 -1 roll oforce resolvecolorspace
  546.     3 -1 roll oforce resolvefnproc
  547.     4 array astore
  548.   }
  549.   /Indexed {
  550.     aload pop 3 -1 roll oforce resolvecolorspace
  551.         % Stack: /Indexed hival lookup basespace
  552.         % If the underlying space is a Lab space, we must scale
  553.         % the output of the lookup table as part of DecodeABC.
  554.     dup dup type /arraytype eq { 0 get } if /CIEBasedABC eq {
  555.       dup 1 get /DecodeLMN known {
  556.     1 get dup length dict copy
  557.     begin /DecodeABC [ 0 2 4 {
  558.       RangeABC 1 index 1 add get RangeABC 2 index get sub /mul load
  559.       RangeABC 3 index get /add load
  560.       DecodeABC 6 -1 roll 2 idiv get [ 6 1 roll aload pop ] cvx
  561.     } for ] def
  562.     /RangeABC //01_3 def
  563.     currentdict end /CIEBasedABC exch 2 array astore
  564.       } if
  565.     } if
  566.     3 1 roll
  567.     oforce dup type /stringtype ne {
  568.         % The color lookup table is a stream.
  569.         % Get its contents.  Don't lose our place in PDFfile.
  570.         % Stack: /Indexed basespace hival lookup
  571.     PDFfile fileposition 5 1 roll true resolvestream
  572.         % Stack: filepos /Indexed basespace hival lookupstream
  573.     1 index 1 add
  574.         % Stack: filepos /Indexed basespace hival lookupstream len
  575.     3 index
  576.       dup dup type /arraytype eq { 0 get } if
  577.       //csncompdict exch get exec mul
  578.     string readstring pop
  579.         % Stack: filepos /Indexed basespace hival table
  580.     5 -1 roll PDFfile exch setfileposition
  581.     }
  582.     if 4 array astore
  583.         % Replace the PDFColorSpace with the Indexed space if needed.
  584.     dup 1 get
  585.     dup type /arraytype eq {
  586.       dup length 2 ge {
  587.     dup 1 get type /dicttype eq {
  588.       dup 1 get /PDFColorSpace known {
  589.         dup 1 get /PDFColorSpace 3 index put
  590.       } if
  591.     } if
  592.       } if
  593.     } if pop
  594.   }
  595.   /Pattern {
  596.     dup type /nametype ne {
  597.       dup length 1 gt {
  598.     1 oget resolvecolorspace
  599.     /Pattern exch 2 array astore
  600.       } if
  601.     } if
  602.   }
  603. .dicttomark readonly def
  604.  
  605. /cssubst {        % <csname> cssubst <cspace'> true
  606.             % <csname> cssubst false
  607.   dup resolvecolorspace
  608.   dup 1 index ne { exch pop true } { pop pop false } ifelse
  609. } bdef
  610.  
  611. /csnames mark
  612.   /DeviceGray dup  /DeviceRGB dup  /DeviceCMYK dup  /Pattern dup
  613. .dicttomark readonly def
  614. /csresolve {        % <csresourcename> csresolve <cspace>
  615.   dup Page /ColorSpace rget {
  616.     exch pop resolvecolorspace
  617.   } {
  618.     //csnames 1 index known not { /undefined cvx signalerror } if
  619.   } ifelse
  620. } bdef
  621. /resolvecolorspace {    % <cspace> resolvecolorspace <cspace'>
  622.   dup dup type /arraytype eq { 0 get } if
  623.   //csrdict exch .knownget {
  624.     exec dup type /nametype ne { dup length 1 eq { 0 get } if } if
  625.   } {
  626.     csresolve
  627.   } ifelse
  628. } bdef
  629.  
  630. /scresolve {    % <c0> ... scresolve <multi>
  631.         % We can't really make sc[n] and SC[N] work, because
  632.         % the color space information isn't available at
  633.         % conversion time; so we hack it by assuming that
  634.         % all the operands on the stack are used, and that
  635.         % if the top operand is a name, it's a Pattern resource.
  636.   dup type /nametype eq
  637.     { Page /Pattern rget { resolvepattern } { null } ifelse }
  638.   if
  639.   dup type /dicttype eq {
  640.         % Check the PaintType, if any (shading patterns don't
  641.         % have one).
  642.     dup /PaintType knownoget { 2 eq } { false } ifelse
  643.   } {
  644.     .pdfcount 1 gt
  645.   } ifelse
  646. } bdef
  647.  
  648. /.pdfpaintproc {         % <patdict> <resdict> .pdfpaintproc -
  649.   DEBUG { (%Begin PaintProc) = flush } if
  650.     % For uncolored patterns, we have to unbind the current
  651.     % color and color space before running the PaintProc.
  652.     % There's no harm in doing this for colored patterns,
  653.     % so for simplicity, we always do it.
  654.   PDFfile fileposition 3 1 roll
  655.   q
  656.   null sc1 null SC1
  657.  
  658.   % save old value of pdfemptycount on opstack, set to new value
  659.   pdfemptycount /pdfemptycount count 3 sub def 3 1 roll
  660.   exch false resolvestream pdfopdict .pdfruncontext
  661.   % restore pdfemptycount
  662.   /pdfemptycount exch def
  663.  
  664.   Q
  665.   DEBUG { (%End PaintProc) = flush } if
  666.   PDFfile exch setfileposition
  667. } bdef
  668.  
  669. /resolvepattern {    % <patternstreamdict> resolvepattern <patterndict>
  670.         % Don't do the resolvestream now: just capture the data
  671.         % from the file if necessary.
  672.   dup length dict copy
  673.   dup /FilePosition .knownget {
  674.     1 index /File get dup fileposition 3 1 roll
  675.         % Stack: dict savepos pos file
  676.     dup 3 -1 roll setfileposition
  677.     dup 3 index /Length oget
  678.  
  679.     dup 65535 le {
  680.       string readstring pop
  681.     } {
  682.       () /SubFileDecode filter /ReusableStreamDecode filter
  683.     } ifelse
  684.         % Stack: dict savepos file string
  685.     3 1 roll exch setfileposition
  686.     1 index /File 3 -1 roll put
  687.     dup /FilePosition undef
  688.   } if
  689.   dup /Shading knownoget {
  690.     resolveshading 1 index /Shading 3 -1 roll put
  691.   } if
  692.   dup /PaintProc [
  693.         % Bind the resource dictionary into the PaintProc.
  694.     2 index /Resources knownoget { oforce } { 0 dict } ifelse
  695.     /.pdfpaintproc cvx
  696.   ] cvx put
  697.   DEBUG {
  698.     (%Pattern: ) print dup === flush
  699.   } if
  700. } bdef
  701.  
  702. drawopdict begin
  703.   /g { /DeviceGray cssubst { cs sc1 } { g } ifelse } bdef
  704.   /rg { /DeviceRGB cssubst { cs sc* } { rg } ifelse } bdef
  705.   /k { k } bdef
  706.   /cs { csresolve cs } bdef
  707.   /sc { scresolve { sc* } { sc1 } ifelse } bdef
  708.   /scn /sc load def
  709.   /G { /DeviceGray cssubst { CS SC1 } { G } ifelse } bdef
  710.   /RG { /DeviceRGB cssubst { CS SC* } { RG } ifelse } bdef
  711.   /K { K } bdef
  712.   /CS { csresolve CS } bdef
  713.   /ri { ri } bdef
  714.   /SC { scresolve { SC* } { SC1 } ifelse } bdef
  715.   /SCN /SC load def
  716. end
  717.  
  718. % ---------------- Paths ---------------- %
  719.  
  720. drawopdict begin
  721.             % Path construction
  722.   /m /moveto load def
  723.   /l /lineto load def
  724.   /c /curveto load def
  725.   /v { currentpoint 6 2 roll curveto } def
  726.   /y { 2 copy curveto } def
  727.   /re {
  728.    4 2 roll moveto  exch dup 0 rlineto  0 3 -1 roll rlineto  neg 0 rlineto
  729.    closepath
  730.   } def
  731.   /h /closepath load def
  732.             % Path painting and clipping
  733.   /n { n } def
  734.   /S { S } def
  735.   /s { s } def
  736.   /f { f } def
  737.   /f* { f* } def
  738.   /B { B } def
  739.   /b { b } def
  740.   /B* { B* } def
  741.   /b* { b* } def
  742.   /W { W } def
  743.   /W* { W* } def
  744.   /sh { resolvesh shfill } def
  745. end
  746.  
  747. % ---------------- XObjects ---------------- %
  748.  
  749. /xobjectprocs mark        % <dict> -proc- -
  750.   /Image { DoImage }
  751.   /Form { DoForm }
  752.   /PS { DoPS }
  753. .dicttomark readonly def
  754.  
  755. % Note that the keys in defaultdecodedict are resolved (PostScript, not PDF)
  756. % color space names.
  757. /defaultdecodedict mark
  758.   /DeviceGray { pop //01_1 } bind
  759.   /DeviceRGB { pop //01_3 } bind
  760.   /DeviceCMYK { pop //01_4 } bind
  761.   /CIEBasedA { 1 get /RangeA knownoget not { //01_1 } if } bind
  762.   /CIEBasedABC { 1 get /RangeABC knownoget not { //01_3 } if } bind
  763.   /ICCBased {
  764.      1 oget dup /Range knownoget {
  765.        exch pop
  766.      }{
  767.        /N get [ exch {0 1} repeat ] readonly
  768.      } ifelse
  769.   } bind
  770.   /Separation { pop //01_1 } bind
  771.   /DeviceN {
  772.     1 oget length [ exch {0 1} repeat ] readonly
  773.   } bind
  774.   /Indexed {
  775.     pop [ 0 1 BitsPerComponent bitshift 1 sub ]
  776.   } bind
  777. .dicttomark readonly def
  778.  
  779. /checkaltimage {    % <resdict> checkaltimage <resdict[']>
  780.   Printed {
  781.     dup /Alternates knownoget {
  782.       {
  783.     dup /DefaultForPrinting knownoget {
  784.       {
  785.         /Image oget exch pop exit
  786.       } {
  787.         pop
  788.       } ifelse
  789.     } {
  790.       pop
  791.     } ifelse
  792.       } forall
  793.     } if
  794.   } if
  795. } bdef
  796.  
  797. /makeimagedict {    % <resdict> <newdict> makeimagedict <imagemask>
  798.             % On return, newdict' is currentdict
  799.   begin
  800.   /Width 2 copy oget def
  801.   /Height 2 copy oget def
  802.   /BitsPerComponent 2 copy oget def
  803.   /Interpolate 2 copy knownoget { def } { pop } ifelse
  804.   makeimagekeys
  805. } bdef
  806. /makeimagekeys {    % <resdict> makeimagekeys <imagemask>
  807.         % newdict is currentdict
  808.         % Assumes Width, Height, BPC, Interpolate already copied.
  809.   /ImageType 1 def
  810.   /ImageMatrix Width 0 0
  811.         % Handle 0-height images specially.
  812.     Height dup 0 eq { pop 1 } if neg 0 1 index neg
  813.     6 array astore def
  814.   dup /ImageMask knownoget dup { and } if {
  815.         % Image mask
  816.         % Decode is required for the PostScript image operators.
  817.                 % AI8 writes bogus decode array [0 1 0 0 0 0 0 0]
  818.     /Decode 2 copy knownoget { 0 2 getinterval } { //01_1 } ifelse def
  819.         % BitsPerComponent may be missing for masks.
  820.         % The spec requires it, but some producers omit it, and
  821.         % Acrobat Reader doesn't care.
  822.     /BitsPerComponent 2 copy known { pop } { 1 def } ifelse
  823.     true
  824.   } {
  825.         % Opaque image
  826.     dup /ColorSpace oget resolvecolorspace /ColorSpace exch def
  827.         % Decode is required for the PostScript image operators.
  828.     /Decode 2 copy knownoget not {
  829.       ColorSpace //defaultdecodedict
  830.       ColorSpace dup type /arraytype eq { 0 get } if get exec
  831.     } if def
  832.     false
  833.   } ifelse
  834.         % Even though we're going to read data,
  835.         % pass false to resolvestream so that
  836.         % it doesn't try to use Length (which may not be present).
  837.   exch false resolvestream /DataSource exch def
  838. } bdef
  839.  
  840. /DoImage {
  841.   checkaltimage dup length 6 add dict
  842.   1 index /SMask knownoget { 1 index exch /SMask exch put } if
  843.   1 index /Mask knownoget { 1 index exch /Mask exch put } if
  844.   makeimagedict doimage
  845. } bdef
  846. /makemaskimage {    % <datasource> <imagemask> <Mask> makemaskimage
  847.             %   <datasource> <imagemask>, updates currentdict =
  848.             %   imagedict
  849.   dup type /arraytype eq {
  850.     /ImageType 4 def
  851.     /MaskColor exch def
  852.   } {
  853.         % Mask is a stream, another Image XObject.
  854.         % Stack: datasource imagemask(false) maskstreamdict
  855.     PDFfile fileposition exch
  856.     dup length dict makeimagedict pop
  857.         % In order to prevent the two data sources from being
  858.         % aliased, we need to make at least one a reusable stream.
  859.         % We pick the mask, since it's smaller (in case we need to
  860.         % read all its data now).
  861.         % Stack: datasource imagemask(false) savedpos
  862.         % maskdict is currentdict
  863.     /DataSource DataSource mark
  864.       /Intent 1
  865.       /AsyncRead true
  866.     .dicttomark .reusablestreamdecode def
  867.     PDFfile exch setfileposition
  868.     currentdict end currentdict end
  869.     5 dict begin
  870.     /ImageType 3 def
  871.     /InterleaveType 3 def
  872.     /DataDict exch def
  873.     /MaskDict exch def
  874.     /ColorSpace DataDict /ColorSpace get def
  875.   } ifelse
  876. } bdef
  877. /doimage {    % <imagemask> doimage -
  878.         % imagedict is currentdict, gets popped from dstack
  879.   DataSource exch
  880.   PDFversion 1.4 ge NOTRANSPARENCY not and {
  881.     currentdict /SMask knownoget
  882.   } {
  883.     false
  884.   } ifelse {
  885.     makesoftmaskimage
  886.   } {
  887.     currentdict /Mask knownoget {
  888.       makemaskimage
  889.     } if
  890.   } ifelse
  891.         % Stack: datasource imagemask
  892.    % image and imagemask can be redefined in gs_init.ps to tweak interpolation
  893.    % after device-specific files are run. Don't bind them here.
  894.    { currentdict end setfillstate /imagemask }
  895.    { ColorSpace setgcolorspace currentdict end setfillblend /image }
  896.   ifelse
  897.   .systemvar stopped {
  898.     $error /errorname get dup /ioerror eq {
  899.       pop (\n   **** Warning: File has insufficient data for an image.\n)
  900.       pdfformaterror
  901.     } {
  902.       (\n   **** Warning: File encountered ')
  903.       exch 40 string cvs concatstrings
  904.       (' error while processing an image.\n) concatstrings
  905.       pdfformaterror
  906.     } ifelse
  907.   } if
  908.         % Close the input stream, unless it is PDFfile or
  909.         % PDFsource.
  910.   dup dup PDFfile eq exch PDFsource eq or { pop } { closefile } ifelse
  911. } bdef
  912.  
  913. /.paintform {    % <formdict> <resdict> <stream> .paintform -
  914.   3 -1 roll dup /Group known NOTRANSPARENCY not and {
  915.     .paintgroupform
  916.   } {
  917.     pop pdfopdict .pdfruncontext
  918.   } ifelse
  919. } bdef
  920.  
  921. /DoForm {
  922.     % Adobe 2nd edition of the PDF 1.3 spec makes /FormType
  923.     % and /Matrix keys optional. Cope with the missing keys.
  924.   dup length
  925.   1 index /Matrix known
  926.     { dict
  927.     }
  928.     { 1 add dict
  929.       dup /Matrix { 1 0 0 1 0 0 } cvlit put
  930.     }
  931.   ifelse
  932.   copy
  933.   dup /FormType known not {
  934.     dup length 1 add dict copy dup /FormType 1 put
  935.   } if
  936.  
  937.   dup [ 2 index /Resources knownoget { oforce } { 0 dict } ifelse
  938.   3 index false /resolvestream cvx
  939.   /.paintform cvx
  940.   ] cvx /PaintProc exch put
  941.   q execform Q        % gsave / grestore around the Form
  942. } bdef
  943.  
  944. /_dops_save 1 array def
  945.  
  946. /DoPS {
  947.   DOPS
  948.    {
  949.      //_dops_save 0 save put
  950.      true resolvestream cvx exec
  951.      //_dops_save 0 get restore
  952.    }
  953.    { pop }
  954.   ifelse
  955. } bdef
  956.  
  957. currentdict /_dops_save undef
  958.  
  959. drawopdict begin
  960.   /Do {
  961.     setfillblend
  962.     PDFfile fileposition exch
  963.     dup Page /XObject rget { 
  964.       exch pop dup /Subtype get xobjectprocs exch get
  965.         % Don't leave extra objects on the stack while executing
  966.         % the definition of the form.
  967.       3 -1 roll 2 .execn
  968.     } {
  969.         % This should cause an error, but Acrobat Reader can
  970.         % continue, so we do too.
  971.       (   **** Undefined XObject resource: ) 
  972.       exch =string cvs concatstrings (\n) concatstrings
  973.       pdfformaterror
  974.     } ifelse
  975.     PDFfile exch setfileposition
  976.   } bdef
  977. end
  978.  
  979. % ---------------- In-line images ---------------- %
  980.  
  981. % Undo the abbreviations in an in-line image dictionary.
  982. % Note that we must look inside array values.
  983. % /I is context-dependent.
  984. /unabbrevkeydict mark
  985.   /BPC /BitsPerComponent  /CS /ColorSpace  /D /Decode  /DP /DecodeParms
  986.   /F /Filter  /H /Height  /I /Interpolate  /IM /ImageMask  /W /Width
  987. .dicttomark readonly def
  988. /unabbrevvaluedict mark
  989.   /AHx /ASCIIHexDecode  /A85 /ASCII85Decode  /CC /CalCMYK
  990.   /CCF /CCITTFaxDecode  /CG /CalGray  /CR /CalRGB
  991.   /DCT /DCTDecode  /CMYK /DeviceCMYK  /Fl /FlateDecode
  992.   /G /DeviceGray  /RGB /DeviceRGB
  993.   /I /Indexed  /LZW /LZWDecode  /RL /RunLengthDecode
  994. .dicttomark readonly def
  995. /unabbrevtypedict mark
  996.   /nametype {
  997.     //unabbrevvaluedict 1 index .knownget { exch pop } if
  998.   }
  999.   /arraytype {
  1000.     dup 0 1 2 index length 1 sub {
  1001.       2 copy get unabbrevvalue put dup
  1002.     } for pop
  1003.   }
  1004. .dicttomark readonly def
  1005. /unabbrevvalue {    % <obj> unabbrevvalue <obj'>
  1006.   oforce //unabbrevtypedict 1 index type .knownget { exec } if
  1007. } bdef
  1008.  
  1009. drawopdict begin
  1010.   /BI { mark } bdef
  1011.   /ID {
  1012.     counttomark 2 idiv dup 7 add dict begin {
  1013.       exch //unabbrevkeydict 1 index .knownget { exch pop } if
  1014.       exch unabbrevvalue def
  1015.     } repeat pop
  1016.     /IDFlag true def  % flag for stream processing.
  1017.     /File PDFsource def
  1018.     currentdict makeimagekeys doimage    
  1019.     % The Adobe documentation says that the data following ID
  1020.     % consists of "lines", and some PDF files (specifically, some files
  1021.     % produced by PCL2PDF from Visual Software) contain garbage bytes
  1022.     % between the last byte of valid data and an EOL.
  1023.         % Some files (PDFOUT v3.8d by GenText) have EI immediately following
  1024.         % the stream. Some have no EOL and garbage bytes.
  1025.         % Therefore, we skip all bytes before EI or EOL 
  1026.     0
  1027.       { PDFsource read not { //true exit } if
  1028.         dup 10 eq 1 index 13 eq or
  1029.           { pop PDFsource token pop /EI ne exit
  1030.           }
  1031.         if
  1032.         exch 69 eq 1 index 73 eq and { //false exit } if  % 'EI'
  1033.       }
  1034.     loop
  1035.     exch pop
  1036.       { /ID cvx /syntaxerror signalerror
  1037.       }
  1038.     if
  1039.   } bdef
  1040. end
  1041.  
  1042. % ================================ Text ================================ %
  1043.  
  1044. drawopdict begin
  1045.             % Text control
  1046.   /BT { BT } def
  1047.   /ET { ET } def
  1048.   /Tc { Tc } def
  1049.   /TL { TL } def
  1050.   /Tr { Tr } def
  1051.   /Ts { Ts } def
  1052.   /Tw { Tw } def
  1053.   /Tz { Tz } def
  1054.             % Text positioning
  1055.   /Td { Td } def
  1056.   /TD { TD } def
  1057.   /Tm { Tm } def
  1058.   /T* { T* } def
  1059.             % Text painting
  1060.   /Tj { Tj } def
  1061.   /' { ' } def
  1062.   /" { " } def
  1063.   /TJ { TJ } def
  1064. end
  1065.  
  1066. % ============================== Annotations ============================== %
  1067.  
  1068.  
  1069.  
  1070. % Get and normalize an annotation's rectangle.
  1071. /annotrect {        % <annot> annotrect <x> <y> <w> <h>
  1072.   /Rect get aload pop
  1073.   exch 3 index sub dup 0 lt { dup 5 -1 roll add 4 1 roll neg } if
  1074.   exch 2 index sub dup 0 lt { dup 4 -1 roll add 3 1 roll neg } if
  1075. } bdef
  1076.  
  1077. % Set an annotation color.
  1078. /annotsetcolor {    % <annot> annotsetcolor -
  1079.   /C knownoget { aload pop setrgbcolor } { 0 setgray } ifelse
  1080. } bdef
  1081.  
  1082. % Draw the border.  Currently, we ignore requests for beveling, and we
  1083. % don't round the corners of rectangles.
  1084. /strokeborder {        % <annot> <width> <dash> strokeborder -
  1085.   1 index 0 ne {    % do not draw if border width is 0
  1086.     gsave
  1087.     2 index annotsetcolor
  1088.     0 setdash dup setlinewidth
  1089.     exch annotrect
  1090.     2 { 4 index sub 4 1 roll } repeat
  1091.     2 { 4 index 0.5 mul add 4 1 roll } repeat
  1092.     rectstroke pop
  1093.     grestore
  1094.   } {
  1095.     pop pop pop
  1096.   } ifelse
  1097. } bdef
  1098.  
  1099. % Draw an annotation border.
  1100. /drawborder {        % <annot> drawborder -
  1101.   gsave
  1102.   dup /BS knownoget {
  1103.     dup /W knownoget not { 1 } if
  1104.     [] 2 index /S knownoget {
  1105.       /D eq { 2 index /D knownoget not { [3] } if exch pop } if
  1106.     } if 3 -1 roll pop strokeborder
  1107.   } {
  1108.     dup /Border knownoget {
  1109.       dup 2 get
  1110.       exch dup length 3 gt { 3 get } { pop [] } ifelse
  1111.       strokeborder
  1112.     } {
  1113.       1 [] strokeborder
  1114.     } ifelse
  1115.   } ifelse
  1116.   grestore
  1117. } bdef
  1118.  
  1119. %
  1120. %   The PDF annotation F (flags) integer is bit encoded.
  1121. %   Bit 1 (LSB) Invisible:  1 --> Do not display if no handler.
  1122. %         Note:  We have no handlers but we ignore this bit.
  1123. %   Bit 2 Hidden:  1 --> Do not display.  We will not display if this bit is set.
  1124. %   Bit 3 Print:  1 --> Display if printing.  We will display if this bit set
  1125. %         (and not hidden) and Printed is true
  1126. %   Bit 4 NoZoom:  1 --> Do not zoom annotation even if image is zoomed.
  1127. %   Bit 5 NoRotate:  1 --> Do not rotate annotation even if image is rotated.
  1128. %   Bit 6 NoView:  0 --> Display if this is a 'viewer'.  We will display
  1129. %         if this bit is not set (and not hidden) and Printed is false
  1130. %   Bit 7 Read Only - 1 --> No interaction.  We ignore this bit
  1131. %
  1132. /annotvisible {            % <annot> annotvisible <visible>
  1133.   /F knownoget not { 0 } if         % Get flag value
  1134.   dup 2 and 0 eq              % Check hidden flag
  1135.   exch dup 4 and 0 ne Printed and    % Check print flag
  1136.   exch 64 and 0 eq Printed not and    % Check noview flag
  1137.   or                    % Combine print and view
  1138.   and                     % Combine with 'hidden' flag test
  1139. } bdef
  1140.  
  1141. /drawwidget {            % <scalefactor> <annot> drawwidget -
  1142.   dup /AP knownoget {
  1143.     false
  1144.     [/N /R /D] {
  1145.     % stack: scale annot appearance false key
  1146.       dup 3 index exch known {
  1147.     exch pop true exit 
  1148.       } if
  1149.       pop
  1150.     } forall
  1151.     % stack: scale annot appearance key true
  1152.     % stack: scale annot appearance false
  1153.     dup {
  1154.       pop
  1155.       oget
  1156.         % Acrobat Distiller produces files in which this Form
  1157.         % XObject lacks Type and Subtype keys.  This is illegal,
  1158.         % but Acrobat Reader accepts it.  The only way we can
  1159.         % tell whether this is a Form or a set of sub-appearances
  1160.         % is by testing for the stream Length key.
  1161.       dup /Length known {
  1162.               % If this is a form then simply use it
  1163.         true
  1164.       } {
  1165.         1 index /AS knownoget not {
  1166.               % If we do not have AS then use any appearance
  1167.         { exch pop oforce exit } forall true
  1168.         } { 
  1169.         % Stack: annot Ndict AS
  1170.         % Get the specified appearance.  If no appearance, then
  1171.         % display nothing - set stack = false.
  1172.       knownoget
  1173.         } ifelse
  1174.       } ifelse
  1175.     } {
  1176.       exch pop    % discard useless AP dictionary
  1177.     } ifelse
  1178.  
  1179.         % Stack: scale annot appearance true
  1180.         % Stack: scale annot false
  1181.     {
  1182.               % Draw appearance
  1183.                 % Initialize graphic following "7.4.4 Appearance Streams"
  1184.       q graphicsbeginpage textbeginpage
  1185.       1 index annotrect pop pop translate
  1186.       2 index dup scale        % Apply scale factor
  1187.       DoForm Q
  1188.     } if
  1189.   } if pop pop
  1190. } bdef
  1191.  
  1192. %  For stamp object we have to determine the size of the output rectangle
  1193. %  and the size of the BBox for the stamp image.  From these we calculate
  1194. %  a scale factor for drawing the stamp.
  1195. /calcstampscale {        % <annot> calcstampscale scale
  1196.   dup annotrect 4 -2 roll pop pop     % get width height size in user space
  1197.   3 -1 roll /AP knownoget {
  1198.     /N knownoget {
  1199.       dup /Matrix knownoget {
  1200.     % transform /Annot /Rect xwidth to Form space
  1201.     4 -2 roll 3 -1 roll dtransform 3 -1 roll
  1202.       } if
  1203.       /BBox knownoget {
  1204.         exch pop    % discard y height
  1205.         aload pop pop exch pop sub    % BBox width
  1206.     div        % scale x widths
  1207.     dup 0 lt { neg } if        % get magnitude
  1208.       } {
  1209.         pop pop 1        % default to unity scaling
  1210.       } ifelse            % if we have /BBox
  1211.     } {
  1212.       pop pop 1
  1213.     } ifelse            % if we have /N
  1214.   } {
  1215.     pop pop 1
  1216.   } ifelse            % if we have /AP
  1217. } bdef
  1218.  
  1219. /drawlink {            % <annot> drawlink -
  1220.   dup drawborder
  1221.   1 exch drawwidget
  1222. } bdef
  1223.  
  1224. % Draw an annotation.
  1225. /drawannottypes mark
  1226.   /Link { drawlink } bind
  1227.   /Stamp { dup calcstampscale exch drawwidget } bind
  1228. .dicttomark readonly def
  1229. /drawannot {        % <annot> drawannot -
  1230.   dup annotvisible {
  1231.     gsave
  1232.     dup dup /Subtype get //drawannottypes exch .knownget {
  1233.       exec
  1234.     } {
  1235.       1 exch drawwidget        % Use drawwidget for everything else
  1236.     } ifelse            % type known
  1237.     grestore
  1238.   } if pop            % annotvisible
  1239. } bdef
  1240. currentdict /drawannottypes undef
  1241.  
  1242. end            % pdfdict
  1243. end            % GS_PDF_ProcSet
  1244. .setglobal
  1245.